// Copyright 2019-2020 ChainX Project Authors. Licensed under GPL-3.0.

#![allow(non_upper_case_globals)]

use frame_support::{assert_noop, assert_ok, storage::StorageValue};
use sp_core::crypto::{set_default_ss58_version, Ss58AddressFormat};

use light_bitcoin::{
    chain::Transaction,
    keys::{Address, Network},
    merkle::PartialMerkleTree,
    serialization::{self, Reader},
};

use xp_gateway_bitcoin::{AccountExtractor, BtcTxMetaType, BtcTxTypeDetector};

use crate::mock::{
    generate_blocks_576576_578692, AccountId, ExtBuilder, Test, XAssets, XGatewayBitcoin,
    XGatewayBitcoinErr, XGatewayCommon, X_BTC,
};
use crate::{
    tx::process_tx,
    types::{
        BtcDepositCache, BtcRelayedTxInfo, BtcTxResult, BtcTxState, BtcWithdrawalProposal,
        VoteResult,
    },
    Trait, WithdrawalProposal,
};

const DEPOSIT_HOT_ADDR: &str = "3LFSUKkP26hun42J1Dy6RATsbgmBJb27NF";
const DEPOSIT_COLD_ADDR: &str = "3FLBhPfEqmw4Wn5EQMeUzPLrQtJMprgwnw";

lazy_static::lazy_static! {
    // https://blockchain.info/rawtx/ca3c38fddbc57dc624a2d747f7124e18867b2cde997c7536173e9ab7c84f546d?format=hex
    // 3 outputs:
    // --> X-BTC hot trustee address (deposit value)
    // --> Change address (don't care)
    // --> Null data transaction (script_pubkey: 6a3b355275573870474374624c4c3775744e38684a50724b4361346a48486944726f36366548565032486e415942476e4d4c404d61746857616c6c6574)
    static ref deposit1: Transaction = "01000000000101d5d64c66952420afe5582da2adeb6e1779d0410873789b90dcbaf8f30d5c2baf020000001716001416c80da74e39737076bf7c908138e0a4bfd39d83ffffffff0300000000000000003d6a3b355275573870474374624c4c3775744e38684a50724b4361346a48486944726f36366548565032486e415942476e4d4c404d61746857616c6c6574f05500000000000017a914cb94110435d0635223eebe25ed2aaabc03781c45873e9e05000000000017a9149f92c872c5d6cbe3e7cbf86478bb6ebadae2527c8702473044022003a42f888a77b171e9e36f87781632f1c8942f9137fcab539909ce0f5bcc3840022034a093ec31c34c380c589c9247faaa2fd0a5166a48008a7078f99a4ab3a9b030012102eefc0fa4093696563c6e1359a0e2716ed56d04823a347f5e8b6de5078a36931000000000".parse().unwrap();
    // https://blockchain.info/rawtx/81fe3bbea2f6c38c659827d073f3aaa8f5595c86add15ae9a33d7139deedbe32?format=hex
    // 2 outputs:
    // --> X-BTC hot trustee address (deposit value)
    // --> Null data transaction (script_pubkey: 6a3b35516f516442516e57584c574c6d414a5666583742673779625a47373141386d35763670686f4b6b64434b50436e4c58404d61746857616c6c6574)
    static ref deposit2: Transaction = "0200000001da3f0a5a9a4531c78aaee288bf54f86f8317954c2f5245da9fb77f4912778078000000006b483045022100b58bdfa1fe2420d1b66c738c1f9dd6cc8eccc815274007edd00dd2b63864bf3702203dcd98681a9caeed5ffafc012131e9b8ed5f9dcd12765c0a151d27058ff7ecc5012103de6dfa8d31044ec6d98146ce9378006aa0570e3143c426eab8ac0920503491f500000000026031f8020000000017a914cb94110435d0635223eebe25ed2aaabc03781c458700000000000000003d6a3b35516f516442516e57584c574c6d414a5666583742673779625a47373141386d35763670686f4b6b64434b50436e4c58404d61746857616c6c657400000000".parse().unwrap();

    // first deposit with opreturn
    // https://blockchain.info/rawtx/d7e21ef6761cea177d662c311d998035df0ed4cf0ebfecc5ce9fe1d481333c39?format=hex
    // 3 outputs:
    // --> X-BTC hot trustee address (deposit value)
    // --> Change address (don't care)
    // --> Null data transaction (script_pubkey: 6a37355532437479396b686d3961573736326f31344755484842634c55315062715275526f6d573333456251705541487853406665696c756e)
    static ref deposit3_0: Transaction = "020000000108d148ef7d3ebd291dba35547bc25ebb1b917ce136d139c51309ceeb5d1e728a020000006b483045022100c45c951385f65d8ed4f03bf73cd6f71943a985e4398ea8ee1375203e9e45b83e022031d4ea3c109f2257e31b2e1db50760991183f62345e969a2347736e5bcbe96b00121039fdabf6c1e8e853bfa9d775f4a7bd155e9fb49b6f596c3bc8a6f5f8fc429851d000000000300e1f5050000000017a914cb94110435d0635223eebe25ed2aaabc03781c458740420f00000000001976a9149b9baf3aabf38017fb8133d7a35a60c77072c76f88ac0000000000000000396a37355532437479396b686d3961573736326f31344755484842634c55315062715275526f6d573333456251705541487853406665696c756e00000000".parse().unwrap();
    // second deposit without opreturn (same input_address)
    // https://blockchain.info/rawtx/987f12d3ebfaf875c19553bf5e1d4277f24d2be64cbdd8942174d1cd232fdaf8?format=hex
    // 1 outputs:
    // --> X-BTC hot trustee address (deposit value)
    static ref deposit3_1: Transaction = "020000000271e9b330f20f27853d40f91aefe6ddaf1571f492700d85fe6b9fd333036ccb3d090000006b483045022100c514ce7ba632dfd0f4e443424585e744025538117b0d6a4eb23d31d1d5d4f5460220596c41045f1a9d2aa06923670b194dab403baf694983380ceb72d73408d233bb0121039fdabf6c1e8e853bfa9d775f4a7bd155e9fb49b6f596c3bc8a6f5f8fc429851d00000000393c3381d4e19fcec5ecbf0ecfd40edf3580991d312c667d17ea1c76f61ee2d7010000006a47304402202c571e1d5af1e78bf841059994940a45b1c7e13cb19cd1868fe981b15ab5d8d902201ae8da5a396447c4f58096f022e96ffc4bdfae276429551bc5e08fa8f36ccaa40121039fdabf6c1e8e853bfa9d775f4a7bd155e9fb49b6f596c3bc8a6f5f8fc429851d0000000001d023600b0000000017a914cb94110435d0635223eebe25ed2aaabc03781c458700000000".parse().unwrap();
    // https://blockchain.info/rawtx/3dcb6c0333d39f6bfe850d7092f47115afdde6ef1af9403d85270ff230b3e971?format=hex
    static ref deposit3_1_prev: Transaction = "010000001e9810073a7f2fdba018da0799f295dec7759a2812b2bc79c1def38756d4dc67bb7c000000fdfd000047304402207b70dac46d4b56b8d305df543fd3c4222c1aef3343d6c397fbe86d08bae1e4c8022020a4cb9c6f3a7a8fd49349926bc068e7e241c1ffa29b6b307cb6ce4f7fa3d07901483045022100d7399195d26b307586c67ad0a211b6be511b1604f4396f70c35bc112da1781750220290d301ead82b146d448de553cc088326042f477714e6cb5c0ed847209872553014c695221034299632a9451f04953920ca79f0f107d2e56ccef587af1be34230f2c24689ac42102b64330e7256416084992276f37f595d5dc6ecdafe4a162568144fe345e75899b21036cdfb2a18d48a4247e3f685863342ed1ef2a6aa07d66a2c45ce53cb65be93b4453aeffffffff54ef448de43b0cc57ce687753e20aa54f143443587a83f3e856c9f985e7a7dfb00000000fdfe0000483045022100ca97c2a2030693da16102f81107ab8b0164c4bf73d49169432c2b18d70be193a022049acb6432b2e13647af768f35afd8d311ec30ded031d3190144d476fa5fe4df401483045022100e82a525bd9c1de7e1895a47e93af5f73c7be2a5d5f8c20862ad922baaaeececd022073dded293cafa4ca9cc07cadeedc22658fa85789139f0e9e0e263b782e330154014c69522103e182e62fd0faced48fab1f009380e2ac6421be95c1e38739e55c00bd3d0a2c6e210359f8c618de0bfe55b20d448ea98dbf4f4b24689889e08892dbabf5a00476b0f22103353e3ba3277d232f235976031bebedf04e44fcc5c67bb9d0f2a574374746a2a753aeffffffff040c328beb477ef28cc0261de7dc178516ecdcdd0149186da87424095c2d444500000000fdfe000048304502210091d53c4e21b43354d59f066f68774ae9d34cbe9e96d1bf931824645615bd0e1f022035401308aeab0b871b6bc5ef5093ea6dd70c36d6c1b2f254e4d737175031d10d01483045022100f96a92f7a6910fb157a7108fc1b78e291be15835a4861ee807b287b4687ace1902201bc91f2201d401ffb4355ec2059850a1f95d104dc83a654775e45b33df814ea9014c6952210246ccf4de0c54cc7f3354cdd993c2c50cf965fd82238b89659fbd73a1b4bf05a121024fc59f72272a897fe43803374969f396058152fe4765a8d15216f94624257b1b21022593bc69ecbf3bbcc3c58082267cb49dadaf4ca8dbf1b2297338a9d628c4297653aeffffffff05c653b24ba9d24f7f9e66b3630f5e3029173b8c9c72abff55a365960018c69f01000000fdfe0000483045022100a1d20a67f5a060551e29a54dbe90f57f0fd6e063e953baeccb3fea2590d2ef8c02207155e4cb9684fed9bfca0c9c98d9321db6ada37a31ee4298c98cd306df03adb101483045022100d136cbb579aa0650efdfa75262bb61ff8c0bb63bc63e851fc0cf004312280c1b0220147945bdc5bad8a06739a1477830f7493596bb89be5e7bdfdcec7becd4a6b6de014c69522103c5dde6c2d6dcddd979a3560afcd8b4bd9732d5a1fedc75a562a439eb81a94382210256abd51eec4fa93a1f9b3ce07b3faad0c3277c9ea8177e35d04820128e227af121024b0072cb9242f79f672891d6275d77c0c8180cb9dacc48886ca5b416644fed7553aeffffffffb3e69d5238b415b8aba029acb331eb8a978ce3be8775dc1a462767c2d4d1660399000000fdfd0000483045022100a0953a1c1b6eb5445ff5dbe0372127f30ef7f250f53a17956f778e4fcc597fe3022025530d1bf25d065acc0e10a582cf2655b055beb8beade4b019f4a461515e37d30147304402206ee2276a09215280925268f5ff91e3e14b9f0a26aec41d6473811c84c5b491de02203128fbca2cd2da243048cf9cf14149028a96b9ea062f170ba1ead96e6204c9e6014c69522103953d07e2dbebdbe59d9cebdffa9b91efec90efb6948a4d73abf49b57d80472532102851619c2377db99fb0f190cc6a081d14f0cbc2a9161d7ad7757ce7a33372cae521031757c35c53ea5ce2e4488b2e6d529f381f28b156ffda0f2ebaebd0a13a652d1b53aeffffffff9810073a7f2fdba018da0799f295dec7759a2812b2bc79c1def38756d4dc67bb6b000000fc0047304402207ffeeb6960017681fdca626913074b7a1cda42fb64203843bd1f91d3adb6a05902204f71299ddf8ac67059f44a1bcda2fd8f42d8abc5212c85222800aa3004df210e01473044022030d9a5e68f3f755c18060b3fa9c0e8d51a4d86c4653d9471384dadbc59a61e4402207b3abf9cee88177979f13f6259f5ae1e96d68ee5d7d09b86795d1a77bb071351014c695221026a72f642072402d849ee59b03b50820b782d14def3304688ca4d49ec0932047321021012fc3632a7852c5dec51a06dd60809ca4048bb61cc52f02e4afb5d25f30a572102e68408967f6211d9a595055d73f9cfdc95bc8932f0c684581648ef972ac407a153aeffffffff0618f17f006bf4d788b821ce3745ad067838da415d8684c954566ad1434e635a55000000fdfe0000483045022100ff78ecccbcce1ac0b2b45272d07941c0cb7299c99a853b70315fe58f39b6ebc6022051fe3d9509d3febf6a29efd42c2275a85e0fc9afe18b7e73024f898de2094220014830450221009049cb74e99a392dbee1371c1a88dff3c72c7ee9a3c270bdc36adc675594b553022007a9bf21e278ffa2238092901722faaed2eaa8a303c43becf77a7f5aa33d2ba4014c6952210206033f6a771f100d6b6bfcfb218b6aceff4864927ef6043ef378a2350ff56cd02102f75bb9f7364ce803edcf4661dcaa6a4f47686a249c1f24e815c4225b5786198b21036cd335f82e03790ca85dee4611362846edf36628abf89a94edebe4e3af90bfb353aeffffffff6e246e7fbe1291fb4b16c6bfaca6e7bf9bdc313c81f9c9d1b65a115a736f15f31a000000fdfe00004830450221008e530bd920253e0816b3e1b1c81da89fb5bd09816598d5bc89a576446f6e7d02022023aaa75f7b4a97c6269affa188f1e82551d4868af06fa24ab3fa2bf62dcd895301483045022100bee606a2aec07cf5d024163753794efb146d97ab222158d1c02c872c73e317c90220723e33a8d66e8a2e3697d7dd411ad1b4ef36b927d5148b185a1f5871a496c376014c69522102456cab212c889b5e99c221b160359ae69c2f8175699baece7cb3419f0c6222fc2102c195c04bbbde91f975c9a0466492cc6ef4cb6e41caedf65f352d0134216083442103eb5abd881e1adcb3579a43d6cb17f8e0aa9aa00af90b36bf7bf6efda52924b3953aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe59000000fdfd00004730440220260d81dca78a293a8a19d1f303cb4e69a0f9f5cb480715062de90048a3e8399f0220301e1bebb30a799e9c94a9007c7d80e5507020ee77fa13690e0f63388587b8ee01483045022100dcf77a80be6b0866ced90eef594dc4fc25b1a281932fb1c2e166c251da10ed48022011b42e360886e675481becff6e55ebdbb1dedc2beaec92dc46186e07b3814df9014c69522103cac5ed6c5119e6e693ce62c2573674a47b14e94a0c2b45442b4947bc5732f6132102972ba6935fa7cd4c636d275bca56414cdf5424ed909af3932cc61a463918037c21031257b67abb7a1b7998288f9d02ef656f0b02c2b1d572d95be19bb1aa64ded17f53aeffffffff655319c0c47c3f369b91544279e551ee7ee1d45fcd61a2e8445d05e21c75452801000000fdfd00004830450221008d61c434803aa3f091fb456d4d7e4c9889b10e80e7cbb6787b205afae931664402204453440646fedcd2310e8bb9ce834da08e9e05e92b6e2bf6431d74d1813ef0d901473044022063d6685e9e5d23206054bccd960cfe789708468254a997396571906e27e942f802205620cb13c17d138376127e8a1c5d017e53a0e5c51c728acdc0b116abfc9dfc5e014c69522103c5dde6c2d6dcddd979a3560afcd8b4bd9732d5a1fedc75a562a439eb81a94382210256abd51eec4fa93a1f9b3ce07b3faad0c3277c9ea8177e35d04820128e227af121024b0072cb9242f79f672891d6275d77c0c8180cb9dacc48886ca5b416644fed7553aeffffffffe17ef2acde755f46041580102ed2c07c5061646a649adbaec44a50e459b785a0ab010000fc0047304402203072642bf6d54994946702b803d54198bf92e18e6f1111d6821aa491cefcf29a02200f1dcbdc6789b3be3cf26d253441d9d359af57651897974a3fbda73c3bbe653d01473044022074b01dd34118db2943afe7c2aca3bfb8a5946b2bc411a8fa99dbe41970637b5d02207ae511eb4d85dd9f340f6fc565fc946730bb56b29c0ae40ae3da01b3ae8d4cc7014c69522102815fa79f66c6ba96dc0abd22e51fd3ce872a2cc44b799a3dde6b150c09a7bb8e2102e3868acd8ca74a98cb25ca936675c0d399425f947e7e15cd057b12efba14a9b5210373f8f6f4f5b2f0c15b81b14f1c6b413a485fa04b6ea18c13b96b90a0647e730a53aeffffffffb3e69d5238b415b8aba029acb331eb8a978ce3be8775dc1a462767c2d4d16603bc000000fc0047304402207b4db496784aa8382b110aa62af7f59577bcc0235a58e3ac126c51ae22e109f7022041fe34d59341601b51ab8fe6c1ac75fc09c2a8908acad420d8776cd965ccfaf801473044022047942d26f8b6bdea3148a7a91a39d579a07990545549d4f9a8201259d22c9bf502202db8c857c32f33ad739b5f38db22ad7e28b093b940e7248e3f2d0c710a1d00ac014c69522102b052bd66ca76d7802eb0b42e0947eff035b02cfdeef2596a56345324a2afc0bf2103d173b9db3a2365d1469b8a8a0bde7fbda296b962a75e52e371286bf4409fab39210292b87350fda624c8a809f7e45538aea7d0d4f26fd335facc88f37c6bb30cda1453aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe63000000fdfe00004830450221008ebe4b581066b496920c66cd295b79d29a51d5332210b926d5d518ef9ae8c9ba022039ecae3b637af0f317db8dd8f44cb25354fd917022f1c4019df02a7b42eaf829014830450221008a8140d5e110349247f2cebeca1f734cd6ad38e16be9f3594f2713d7c86f0adc022064f91f71bb70237fb88e64d3a4537c0de868f0a670eeb4bd4623f336f890d516014c695221029152d130ba3aacbf96caa401381544239215eb349369d0e4e648c7375ff0de9321021c8405a3b020aec69c91f113b6b51d3140d0e951c141d7379ae3f1e9213f7ff92103592679bad612cd57c40f8f88bd808fcce2ad541fadcbc73e9c72a2ab6f9d56bc53aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe12000000fdfd000047304402203c25c919ad03b5e2f7c551c025f25179fc70ae050f2ec8e5596aac34ca3779f002202d3d0f5ac1c1f0af9c17536d918f304beb6c13fe6a7e8912f2471eed3088950a01483045022100b0a3ec3a9c8c0f5e69809262253a7274d7ee42f43808279591a8375871766eb5022019e24d065ae054983ee556aefe04fe7625e01ac14899f46f1b4828c2593c7e2a014c69522103cafb089428a6a778985003947e343ea14857b1e41785364aeb2da965e5a8c44c2102426e0bbdbf70421a005862c6112dcda5c8762cd87ce1daf0cee03d43c893825e2102972a10833a5acab126a82dc6ff51ec77abdd5165543e346f46a45d693fa3f6f053aeffffffff6087719486f313b1a05d278a193430f4c930058075dd8021745106d4dea84dd021000000fc0047304402207feaaadfdd9ecfe468efcdde1c63afeaa5001454ce890908f9eddaf5ffb6057302200a488ac92d091d4882c8ffa680fe2320284bd9c9c34189155a87ee0c4449e26901473044022052baed55c33fa38c62a715840c3b9098d426ff144962dff2c1731a59b7a5f72302204f5c48cbe354ccb6bec9f010545f7dc45734e46e96a2a0712ed5039e8ddfe31f014c69522102463877cd7d80bd5004f4a4d64d96c54a81d90b3083b6505585c0bf2c626c3492210395c4b4de186edc9942c2448cf6b91389cbebba661b58be78f5ac38d2fe87a68c210220119d073c8e208b84b4c568af027d9fd71b4c057dac765d260295505e16284d53aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe23000000fc0047304402202010609304395875b8b2b4687e05bce77a78f2e8a004773a766e629cdd7e87cb02206e5c9b67ce4531a48fd9acb19555f4eb291521aa2a5120e204735d506a27bc2f01473044022046ebeeb53e0a9ebaf5975b42f347b0058304fd94b91f02e899b33d4abfe81dd502206baa8902a1f33b6af25923940085e13c02b069824584858ab37c3f36d9169518014c69522102fe8e9163f7de37a1610aa86cdbbe8d045c39040281330f5fc094d786c5d399c4210232a898370f01939a93bffb76dc24501438aa0b4631679909d5939028d5e4faaf21036517f58878609cbeb6ce042ae43551d1a2c831f89a3e507ba4331d529532f54753aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe1b000000fdfd0000483045022100899fad5ce6092ad43e7f33fa8414c6894def827a03a16856f858b6278b5d0f9d022055490062540bce3e15c77da80ce3358262014427679bc415babc7756b65d12fc0147304402203f8ff1a2785cf98fc0625da40f1467c9c9ceab9d25d00d8851d721d55020241002201f600f59b50414e77bcdea74305aee6524b5a2294f51390da4254e5b454c543e014c695221033740ed9fa2bc099540509d6f956e07ff288d10a8f192f2197027499e0963703b21023614a9395b29b591a668bc0a36a81ec97de826ce3ca85b0f7171ebb186e30c6e21021f3add7b65e2273cfe49cd78b9fb629dd5135d0efc40312572bfd3aa0418152f53aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe1c000000fdfe0000483045022100c177f427dd37e085ec0232b5077d020b2ec0b77a7dd3a59a5aa40da8e51fd1eb022011c5531a6fa3f7bf8f2eade4d99b6d91d725ae3757549e1dd91023a9abc111eb014830450221009db01fbb78b8af9c44c3fac66042432d83133170a4e5f2da21534f6be0a4893a022046e01c09b657ef64ffd01cbab1a9ed596786b25994261ddfed6393b4c04a24dd014c695221022ff343078c45856fbbd061a23d67993b149501c8e99e291a7eee5fca03f9006d21032ca6cd9dbd3e6a72b0a147b90eb6c46700fedbc7a141bf6c05a8bdacf36bc8e421038d3485e36320e690e6ccbd4a7b327b91632c8b7a998d27ea3fe63e55ef98c94553aeffffffff8b48b64156c668b769a04cd6ad477ae8a41fce92edde81342877b40386124d1000000000fc00473044022016df28e0d87fbcfcd50470871d6d9b4db5ddd535671068ebaf9aa863e5a7df720220306eb72bf739c3db1ffca998509fa4c9261c7769bc101e36bce9217ac7ccfcd50147304402206869435ffeb7f01a67390a0b30a57d28f7eb0f3329f19f9108e39bf6c114c9cb02207d1b1ce09aa7190980ad3c83f0a4149b0d9aa926158dbe7530577c8e80709786014c6952210246ccf4de0c54cc7f3354cdd993c2c50cf965fd82238b89659fbd73a1b4bf05a121024fc59f72272a897fe43803374969f396058152fe4765a8d15216f94624257b1b21022593bc69ecbf3bbcc3c58082267cb49dadaf4ca8dbf1b2297338a9d628c4297653aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe4b000000fc004730440220451cb8e86f3c92dbb79ba0a0431143a8223fb1fa0439dd529937457b0cb10ace02200a92f3a52186a62efc6f3a78dfe942c52db178b79df48a887eadba2f725b25be0147304402207d557fbae78d522162ceeb7f5effcfda10b1bc8dc01eb2288fb85616bf4ade5c02206d2538fa922df63782848f61e7436c7220dd370cfc1333b3fdea26cfd5d94a77014c695221025c553212112a30c34dda8b0cf4728d78ddd2145d5a2c2a3cb72901cefcd8a3222103b117a389ca27aebe290751798913b7fdbaeb44101506b3a07d2099113954c68a2103bb009710548321c20b1955f7de3f085125d161ad5ed0b1407f74e6fabe65776f53aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe2f000000fdfd000047304402200e9e3642e257e63487489390f8b069a096d7f3540ca30474ee1542b92329fb7302204bdc89e3fc39658aaa44a33b8a1dba86b47318d71602732ff7de3d628f132ff301483045022100c850ab8bca1e9f2b30cc8640f256ec9db2df43cdbbeb9bfebafee688790903aa022015289807cafee22bcb506d8d15f72b2a90d1b55bdb91c359b2e735d19d7fb109014c695221034eaf66a9a16bd4b8bd0a04658820dccb0e188894c68d078038dcb3432cdccd10210268f46a160b3ca8e7c54050969876c446d1a1bc33a9c02426210105d3caf85672210339fa85442f2285a6d0fa7abacb8c9221df207c7cbaf98888e9f3b6defaf6383d53aeffffffffa98bb2c88aad40adec0476284e49fd8ece15aed96230113e2d832f1bc9989bbe5a000000fc00473044022046594718acb35f5664e801aa3997ad51a7e34b9d7b53756cf48b3ee1427830c202206a429d475d0c55be420452bbfcaf9ce4c6f2507759011e0d73afa18d02939347014730440220775da183bc1ce7b318e46669654003cf70afa5cd9baf5be71b378c8ce06806f90220045bc9c68cf722c400dbcdca2675fbde0cea1a46edcaaa287971710515899e98014c695221022d521a097b26c2e4a769f844a06d20810154123346c3ddc0601a112060bebc67210307980c4e487b6ae32a0328284a6b340619f3d5589ae199135a9c11c1999c459d2102c1505ea988df93ed96eac0b164a7258f8ca45848d67ed9728ae550812f021a7a53aeffffffff6c54f3d95a53282f0c8f856530048d2a096443ea7f0c5f474d7f81e30bfbd62a4b000000fdfd000047304402206b5e8482ae8b9a85ba69f092e8835da917c886111b028d7e7d7eac835259f57302204973ddf51aeec0a29056f753ada90007152784e5e53025e6af042148f918956d01483045022100c97548b6a574bbd91a2a784526aaf5b42ccd47225eb2c4681c2e2d3baa6ae894022008bb7fbb888de55b6a4836b62670084b788e5759d01f3097c6c4116246602b08014c69522103b5914869b5fb3edeae0b7e64351ea07c6d862adf16803ed8bbb83c82bde9f5ba2102f442a7e7c5fc1b86e8596de1590ce817ca752e4499c6db50d7158962435b5d6a21035f0e5e6cd95987cf854f01a6e14b9a6a911ced8c96c3884b8db1adba4031755b53aeffffffff6c54f3d95a53282f0c8f856530048d2a096443ea7f0c5f474d7f81e30bfbd62a3b000000fdfe0000483045022100830b06aa31be237a3c7a04685a08ad75b092c00bc2dc69791f5f3d038c1251f8022000ea24d6b3ceeab66f7604d53afb38c75433927681cbaa7f2361122760b75cf001483045022100d97761b5e491dfffe6071c962dec8a866126a8991728e1b18c75c474784551a80220569d2f87003a7ad295e28fae1de7f607157f1f41eddc1cb27d4143bbedbcb4c9014c695221022d521a097b26c2e4a769f844a06d20810154123346c3ddc0601a112060bebc67210307980c4e487b6ae32a0328284a6b340619f3d5589ae199135a9c11c1999c459d2102c1505ea988df93ed96eac0b164a7258f8ca45848d67ed9728ae550812f021a7a53aeffffffff6c54f3d95a53282f0c8f856530048d2a096443ea7f0c5f474d7f81e30bfbd62a5e000000fdfd0000483045022100f0cc9ed13689f184d8b8ff837bece663fc97c288062f1c7231e645b8bc6586b102203187d8ad65a2cbd33e695ac3a650ca1c69a61aac618f9bdd88d3ffd784d0a99f0147304402201ae90bdb4df13664a595c0167aa24858eed0b12e4194c899a35528ce20bead8a022023093d1c42d46255edfd3991e4ecf7ea3055c75f62f3c2a50b67f570ee85d2fa014c69522102d86eb90c5a38a7c38d16740a9e86129193c93fec4167a16ad1c3ca3cfe69e5fd2103a628028b7a3530e8550bf2d75bd67ffe03f3b9e8fbf8f316f077c307727d0fb6210363000ad2543f27fda33b54b49e0778b9744274a9ba1870e89444a8d28a9002b053aeffffffff6c54f3d95a53282f0c8f856530048d2a096443ea7f0c5f474d7f81e30bfbd62a1a000000fdfe0000483045022100a28bb2efce8018060a7fb7d149aeaacea5377f474aa2e397e14821075883558e02202e3bd89c95f2365c9717067c6abe0fbf5f2f023ab074fe1e0628f981a9aa024c01483045022100a5c4928612894bd65e68bc8c7284bcc087f51f67e438284e0efbfa9283eaa82d022005c31d82172f9b24b2160de59b272311eb2dd9f0550e3e6e25bda7f041675dbc014c69522103ba7b6ba39a92cd5513d4f0fa9367779ed077a0b4bfa4fa07db9b95ec764250fc210239b4b0531d4f7c5e110ec110a8284525fa8f35c76215f810502e4a00cf94bbf32103e091ecfca1cf282801fca9208c22838a303b001ba3ef12a9f5bca2bae5b53f9153aeffffffff909a5192c354cba73748c2eac5bd74b24a5574ca2572db84ed8d41b011fa38af00000000fdfd0000483045022100ba3e8001e96ac7587bf435d6926402bebb746c3f6af8f8a2ef6a55815e1ba00302200c1aa1500b5f97400f14e2d9a1ea3c94f4eef9fcd25f43098b0717ae4220ed94014730440220648471ad6797ba0d26249735f0a931ac7dd9465458519e05d9b61efe0667739a022051a1c1fecde4dcc50394f36ba6babfdd49e229a5532b225faca20c982b2857dc014c6952210246ccf4de0c54cc7f3354cdd993c2c50cf965fd82238b89659fbd73a1b4bf05a121024fc59f72272a897fe43803374969f396058152fe4765a8d15216f94624257b1b21022593bc69ecbf3bbcc3c58082267cb49dadaf4ca8dbf1b2297338a9d628c4297653aeffffffffaaeae71fddd3adf451a29688d86cebf554eeb78a0aaffff10da08bd3b38e20e401000000fc004730440220485fb650dce126a49dfbb6965cfdd63d6fbde0e232fc90d1e639b46280e85b4702205244c670d515cae53bb8a7cfddbc9fc781454254d91ddd93cae1d9b459fc3493014730440220644273e73f8bff2db8b4e2ae833708649e3a3914b61177f9b51fbe1c44c21f650220064bfb219e7bc814a5c4c62b83df1d054151687697bf999e2a5845bfeed5423c014c6952210220503a54b4ca240ec155f284a53d977bffb7e61f49c957dca3058f249271497d210358a8d9b948f1e36d59133ed83dd45d392fbbac1d24b619a92f5c477d0aa3b9cf21036990c71110bb801fd781104c60654fcf4bb1827e788931d5e59eaa70025da45053aeffffffff89fb40d91d36acce6bd21fd446fcc7e9c1f5720d52e1a88b77c7a24ed87754fc07000000fdfe00004830450221009b401929bd343ddaca4fd2a5e8cf031583e20d8d298ea721e15e8b0f2397da6002203e73078ff0d2006da2524c54250f41620b76d401b509c30e60fc4d8af6a949370148304502210088987da4983b98d61916ffb445c036786c3d5c0997b32359e17144bedabf8822022024519d8c29e11b37b5aa1602ad5aaa2af9704722081cf7f9ec7c7e6ba6c23642014c695221032ef42fae5c21bfcef03c31981dc98e6bde4e758dc8f1eb66807bbc12e9f530382103f2dbfe7cebdbe7fcae526139d90c982b802f2850ea3793a63da7bea3d942734a2103d3244049f9a2c33386d1fceebfb39539b903f2b6f2f54450ce43d6eaed73aac853aeffffffff7c1bb5ac434b333967852754305774c89cdd3b378dcdcebd2a008ccbb3f6e87b06000000fdfd0000483045022100b2c03fd669c4a1bbd84a9b1b0aad7875cfe2d172579a310e8210ee6a9f0c2186022069f5a8f666a6a9d997526ea65d65ab212d3e682c854a0e94f8a5cf39906edd7a0147304402201393ac7aefec0c9f212dc4bf80691554c8a9cab771dc32b68d63be5acf77202802200bfcf9cf16949beae2f4864074309749303532f2d7a0dd070090022829ffa18d014c695221026f7cf22f8cd59a73b141258509a1fd16d65547c954100b576e04cb35dfbddcd121023fe4d478fa62ba1cbccaac12c30450dbe3b380fcc47b78a498cd6be58167f39b2102424c758d9e6ca07e973c4f9888a2a2051a6eaa6ec52b3db9c58d07db061c76fa53aeffffffff0ba0d6c4000000000017a9141864100c350ba903d915165bf3d6bca866f0440987e0b85a02000000001976a9145cc68694401ec6353e0a19e04abf6e66366dcee288ac80ef9801000000001976a9141e3c4674cc7c69673b80d715654792790e92ddc688ace047331d000000001976a914e3574f708cf0cf99cf55477acb5b94d5a930a6b788ac60e31600000000001976a91428befec8d4900707613aa3deeacdafd56c2da41588aca067f705000000001976a9141f6d21d6a58cf152d3960744977ee2eb2a58239088ac00801a060000000017a9144c6d7880474e5a0ca28f922126797c0b68635bb487400073060000000017a9144c6d7880474e5a0ca28f922126797c0b68635bb487009f2400000000001976a9144457b9313a5a012749e290a1073716134f7a03e888ace0a4510b000000001976a9149b9baf3aabf38017fb8133d7a35a60c77072c76f88ac303b700d0000000017a914a01abaca21c0fa16c8db8bb7166b3c4dd12cb2778700000000".parse().unwrap();
    static ref deposit3_addr: Vec<u8> = b"1FBnEt8sFDpCbjExRE8qPpn56D8yUMnYtw".to_vec();
    static ref account3: AccountId = "0xc1dbc157526183cd13dc1f93078831911ccdcc0bd43c174849f577a67580dc78".parse().unwrap();

    // first deposit without opreturn
    // https://blockchain.info/rawtx/7cd6d752c51100c7bc51657433b52facd04a0fea203b8e7776e6420c477912c2?format=hex
    // 2 outputs:
    // --> X-BTC hot trustee address (deposit value)
    // --> Change address (don't care)
    static ref deposit4_0: Transaction = "0100000005ba2f5732c2ae802b210dbe78fc00958f1ed9bbebd3723d5253fa4172034b2872240000006b483045022100f1f38a4c83b18e71a195cb5193a7399b509d98ca07eaaa2a0dca3259e4bd1479022066b89035e74771f08fc37af157a9a56bbcd268d76beac6ccefc3191d05b0fdbf012102f3b58c9d46bd364d056694a7e63193c37a546454011ac140f29997fe2e3ef41dffffffff10dde2ae4706e13999812d986205a9d0d2a559f43674d02ae8059db9e32988bd000000006b483045022100f7dfba9f8d36a3b7a3a5ff3793fab4578e60de71e8ac6c678170fc68fca6fb71022054ebd5d3f62cd939b2cb2e82f6c7411b21f955def0544df09c612e6b4d88c9c0012103e14e6d05e4d336e493081fce0d9be4fffa8995e7300b2297c3feb374be6689d8ffffffff4bacda77b3831cb63898b68fa48e7315c895c5bb162b7039f8ceab64eaaaafdc030000006b48304502210087ee25f8d85aa71d14b270847d275011a0da7dfdbbcad8a0b28197ab9a5f7e01022006b8fdbe33b4798f5a1bbecb835213be4911e36196c4d8a6f0bb7f3072cb29440121020f3f25988db21697dfc31889f690347633d5d719e2abcb4af7c543b0d5daab20ffffffff679acfedd7a4d6ab980b99a0a01e13f69b6d2fd46bfed28e074f4c76664341e1000000006a473044022037463ffe3316ac1c04e54985611e215eebcb4b21b555fc1185aff9b452c6835e022038bf2fbb05755974c086350a49d4447889717468d82cb6e78e832a82d408d16701210270c925644255620e2c7cdc139168789cfa741b72bdd67fd786a7d47b3383fddeffffffff9180948c011ec2de2033c735ec2521248fc9dc3534a46aff690cd7e635672ef3500000006b483045022100adc65c292afe37304089d36f7f5c4ce9cb7ba17bbf712bc86515d9085b7455df022036ebe6c9b742ac3fcbcd70460e1f9199e97c33a86db7b31afd15ff408de8ad1a012103c4d35070efaa5c7e21e5a2ffef4e7cee2e953b3150413c88ebe8ffb63ecb909affffffff0264954105000000001976a9142612bce859f8a024728ad38f455c65d107a5076188ac00e1f5050000000017a914cb94110435d0635223eebe25ed2aaabc03781c458700000000".parse().unwrap();
    // https://blockchain.info/rawtx/72284b037241fa53523d72d3ebbbd91e8f9500fc78be0d212b80aec232572fba?format=hex
    static ref deposit4_0_prev: Transaction = "02000000151eb261146c2446bf118b67d29e5d29c07587bb39f99b77318acc6724493f7521000000006a47304402202833a8f233618c6fd754ca576c2b884fff65d0a955eaaf835b6b44d6bc80f68802205cd80c5757af0bfa043cb34cb74f4413acff4f771407891a7610f142a6e8f87f012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff1fe76d12c0b045b91c9fdbd5160ea52d85dfb66a6446a9acf9da99aee1fe753b010000006a4730440220530ae728001c206f1a9064723c17fa808395590b122a0e59432525543e11f50202203de03304eb09e927b45c0f34a36eb1e19bf1431fdf4aa9e7b4eec66ed3773bce012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff3465f7279fc18c0dd305bff763d55b3da2df29f2e30feaa6f1dadd4bb3fca14c000000006b483045022100cbe2ba296d4a81f81a27a41ed40b5cea82f66d91ce7bf45d0761903010b92914022031fe993963c596981f11cbe24e5a56da5aac19e4724201e6fc5de6a91cb40b6b012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff3a2d1d58bed9502fbb4134b111534884d6857f2a6ec6053f18e92ffdf01bc78f010000006b483045022100e65914218dd6903cb0baf936eaa10faec9a0044399b5f82496e38a78176b54f00220636dca472e77ca2cf87431dfef751f48bc50b9ebd00d9549930d7e83c7eea803012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff4ac9a098cf707deee2854fbba2be16b97db7483d5e0358b09136e168cdd83e8a000000006b483045022100871ca7eb7f2002cb8ba1db49681a902ffdbf16acd23de35c304f418e7d5426cc0220288645d52eb01cfdbfb360b93566ea84e636da0f4c544a19118d92507d2d4c1c012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff4f67efc8ea74d8f0982a5c07171af65926a4e74dd249688066ea54cb4c221ac3000000006b483045022100feb2f356891a1ec308df174685a00c3ae0f35fe328bd9b0a95e7b16e62e0fb3002204f01ab57406e6fd6d7d06540af81c81fb6e9f7315fc7e3e2ff98e1b3145c3f5f012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff60e68fbec84ec291cf5ec671167ad78d195bbf6c6d8b357e1ccac81b27b973f5000000006a473044022040a8d24ba9050d49e139d66f9832ebc69b3fcabb7fcc03f5c73b6d5f88fdabd402204074568ea8a534c1b3a38532ecda5d9ca7908b66f733142b8f8470371642d711012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff719fa5d98f5177ff4b05cfe587ae66ecd97b4bda7b7274aa0a99d7dba6168ae4010000006a47304402203e359b607279423f958458b9083fc006e2fdafdbbfe1695a5a6605fb981fa62b02207a6723e3e934ed3511d88be6c3a2cd2b830ea109f579b602e56a7f0dbfb167fd012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff8010adc002cbe59169493038de0f2c2e5905c79c0cb6b17bca1bbf66567ae60a000000006b483045022100ecc3adaa5e85d47ed5200edbf97ef02cdca9d23e5ce5b7e7fe7d0269b52cdd6302203a3c75ffeb8574c204c2d0e31cac8a13281e6110aeba6f60f4be3bd319602897012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff804576d0b6c815cb21479586320654e434a2b58c4b7f76455f6a5e41ae708035010000006a47304402204661dd4afedb232036d072c464944ad561ab99ac1b83dd572dee982d83aa6524022044d77b016ca2f3c68226feda22024b16ba989d8a2c067dd8dbbe82baa35fe3ef012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff810661259d4314217022425d790ff5852f043779863ca998dfbeec995f5ab01f000000006b483045022100c0cf153abb890cf88661e1a2e4ecd5d0a9d33fae1efe5d58b86c18d6be95f39c02200ee24c90f8684f040b279f2c9374f625dec2fa8d7f38df7140724a34ca4bb8d8012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffffb0a0b0619db5c9d51504414a417f2c0dfd5c6ea1e40dfca30dec32d9a8b16f84010000006b483045022100efb1bf92b097a9ccb7f5c70e1d5c57530955d3ed2741649b98868a0b019a60ed0220209bce33b0c87120404b906d320f0e95ac44c5b41ed4e24ad2d7688e17533197012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffffb95c298ae8fac28018d5b0f2db371f652ff9df7a747eaa86bb5e7e56f95862e3000000006b483045022100adf612b9bc30c33fa583db57b0b30b3dd3afea4d7aaf1d255799bcd32a64d8f40220379e0d796e2da30ccee481ca35a3e0435e064c0289a43f667a53744645df7920012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffffbb108f4b13142d60a4c1e941dade6f88b0e11e9cd5722635543db1c3becf4e4a010000006a47304402203ffea3e6e77d253e177f57acd04931290bc95a51ce6ce817844caa01a7834b6802201f5d148ad1d69c68d430e29339e55d84c5c42c7c96e6186e89482c7e21030524012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffffd1951fa2d09fe924b9389fbf5987e80382f5645e4c18981ea1df8b44766b0aaa010000006a473044022044aacc6d6c5bfdb01ba9b8b634a7d963d3096bb7223f5994e6901042df39bcb00220249661d6697ee321926bc73d6a037ac98e3fb8affa0114603bfa5e72b982821e012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffffe05e2152f29f8e896f6ad36ef1b1562c31074ad9bdacd17dd619cfb189d5770b000000006a47304402206fa162df14b4149f368c93c5cc17549dcd9aa8c55b31c44b9bd092f4b7168dfa02202dae2c8e05c7ebfca9be65842c9826112a1d732faa900235b8538b1a61d2f955012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffffeb3b565e0399e2a22d50dc977331a2d0afb2eeb28c9850fd815d606ea7942f85010000006b483045022100ea0b820d413179a1ae7861a552ba51fd893f5182f4d21e3ffdadd9a8fe6e0da802203a921fc2103ac597b31abe592e56313cba93a80df11294620a17efc79eb9018f012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffffefa99d2e967b54be082ea80c0037f69c5cbdfa7372c5449caac25e5d655d3151000000006b4830450221008fbc49a2e3ac7f4e4a1b9dd13613e3fee1b846b3dba3c3e5a675b0b54e9f002702202bdccebef854d203aa8b07501780937c0be1ba161a1cbd7db06067fcddb699e4012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67fefffffff88b851c6246d3d7962619757112c385492a3607abaceb59baa82f69f324c3c2000000006b48304502210097895c8f22bc719d808dd3c1a0fc012b61fccde7db9485bec490951afbf989ad02201ae0feaefce460e9d52aed1d995987d454ad49f87b705f5924ab42187502b623012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67fefffffff8fdbe65b2387d0dcd1ad7f30ac5ef1d4751c0c194fc72b06a7d90a7b27031ed000000006b4830450221008fe730054392b05d846d56f192997915aaecf2ef29b76c345da4c2bd56024afb02201b7ece05be427b41f8ebb3df87c5fb374f8f872704bfbf9b43c239c9d0ec463b012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67fefffffffbe0c3f59bd6136f3f85aecd9c9bf6322657b6ee56e88022a2b1d94c09aac8f9000000006b483045022100e98b25392e112489920746f3ea26b27cc05c0d040cefb5e3e6522475c90300d60220274d7657df8787da3263262377b550ecce5060c28fbc25ecad6572fb49bb004f012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff31809698000000000017a914968931fc5071a3b03076f4299b1bb1aab479dafe87b0feea0b0000000017a914e36437148389c5ffe66d73344717609fe880b69987002f6859000000001976a91463b8fb658689c38e3b1c2a9eeb18eb270a05767288ac4855a101000000001976a914bb029f065bc492604ffc78dc310283637f16e1e888ac0060343c0200000017a9141f3160f2d0d4313d50701540bbdfeea1237b5e3487c2d32b00000000001976a9144f12cf6bc694c6ad0c6d123d28848b349801efb588ac506225000000000017a914eb5c36ac5b600c5c4518f27a1bd247354865d59e8795ab7d000000000017a91477a70deb4865102665c94e61899790ce6e991ee087d0505c000000000017a914e7e44e7e205d745c99d723296c9d6b80541fb7c787e09c4100000000001976a9145ab84f4abbc2360142e333587393594bbc96eeca88acd83f9b050000000017a914ff15ec7b7bab67d616769216483184d65e63e6bd87a28d36000000000017a914337427043779adc3619000904ad0b6af3ac2db0487b0200b54020000001976a91472e17635d92479b35ba60ca33ed7ac71b4be84cc88ac253698030000000017a91407b85e15bb619d6b79a0c43f4bb8b5be6b948cce87a68778000000000017a914fbf07a16e763df1021fdf5dfe2103bd697f76c2587f274dd020000000017a914f6995fa911eea4d4007eae5d3e7c52683dfee55687706408000000000017a914d5c526e9955f7712fdfad37e5c31da1fa3e8886c87f0490200000000001976a9142545ce2e3621f9b33c98c935cb289866ee802c8c88ac90b45b00000000001976a914f08cfd4ca6e1ccad565f5c193c7bf099ee55701588ac6815c0010000000017a914b24a7d0254b81d3020f414684c8737a5a31ac075874047f9060000000017a914f3751e740c823f1a97c9f7d467cc23c932b00bb887e0c416000000000017a914f8acb1d05ac9185fdf0cde26ae3078ccbd419dda8767254900000000001976a914459d4033dc66b61f36e95ef7170549b222eca39488ac8fb273000000000017a91489e11c565d23411281f2376b503eb716addef5a08766bb3800000000001976a9147a7bbee2449e440e41289a87a109f3b2a2cdcb4988ac8ccc24000000000017a9144473445715377b716e13dd787273bd1b897c0cf48730c11d00000000001976a914cae68f043218bdf52dafc6a57076ac269b27a7b388ac80969800000000001976a91450e7e05b1414c783d4f17133d0cf695e5f657f7488ac4c838c00000000001976a9146dd10b028dc366a3e2df35f4be3e3f6862ccad5f88ac106972000000000017a9148ac62956071f280de8123a5f0ea726af472fa95f87fdad1d000000000017a91464bf2184bacd5fdce6356fd6931b7cd54a6f1d9187694c1d000000000017a9141a72b00394dfc65caf2adbdf731dd52e42e1aa5787323bd100000000001976a9143f5ef0af0756a7348fdb2ffa7f15c2b6642d165b88acbcf53500000000001976a914c3684db0249286b27ec05a119e58f7a82f1e2e5a88acb0dfe0110000000017a9149ee544e444c54e04ee48f2f0963fe74469a0578a8720a10700000000001976a914403163606f6bf8028b010569cb4528a28d479e6788ac80969800000000001976a914480d71e0fe8924b38b5af9392086012baa2009ae88ac600269000000000017a9146552754761689b074fac7a04d3a7bc2bbabe3b2987322492000000000017a914259ae15efabad51a911bc038d4ae67b6700ff06487b0c39203000000001976a91401ac94b1665bb74882de0d0a306e46b002ebbe3688acd07c2b00000000001976a914923b6214c92133d8b657fd6d3acdbd2983a012ae88ac224007000000000017a91411ed9b24359572f7ab47d0b76775ef168e6fad9e874a090800000000001976a91444d7a3fd4481c4897cdd4c86b592e752a7c0319988ac4a976909000000001976a914cb73a8b16eec1a9e5deb335702566d3c176b4fb888ac7d1a8a01000000001976a9147e9cfc1fdf26438ce4585f54ed353c3bdc2a980488aca8734800000000001976a914daf51cc4401017bd7e30b70932b2480f156f83d988acbaa74315000000001976a914473f3eea47e73d32e76dfe06ff22a3fc71e6c76688ac87db36000000000017a914a1b79b4740dd49381f6903694c57ec82f5eafcf387ad7e7100000000001976a9142f312fdc36d120a375c57fec44affafaae5cc74788ac15190800".parse().unwrap();
    // second deposit with opreturn, release prev deposit
    // https://blockchain.info/rawtx/8534ceb3ed643d38e39ca7dde28a95697c3c17883da09f86c5aba20e727ad72d?format=hex
    // 2 outputs:
    // --> X-BTC hot trustee address (deposit value)
    // --> Null data transaction (script_pubkey: 6a373554343664627135466971413932337a775375463465474d483943637238363968374b6675664a5970635434456d6d61404f72616e6765)
    static ref deposit4_1: Transaction = "020000000159d4312ff4106a75dfe4b4918ee03c6af41f7c3df42d42b25506cbdf6ddfcda0120000006b483045022100cad90f1457d171b724d36517282896a9c39e6e00f4ba8b0ec83a354fa17bf26f022037da3f9d73f2a459ea73a3b2e415ccb7351e13804930baacc38bb48786635963012102f3b58c9d46bd364d056694a7e63193c37a546454011ac140f29997fe2e3ef41d00000000026fe905000000000017a914cb94110435d0635223eebe25ed2aaabc03781c45870000000000000000396a373554343664627135466971413932337a775375463465474d483943637238363968374b6675664a5970635434456d6d61404f72616e676500000000".parse().unwrap();
    // https://blockchain.info/rawtx/a0cddf6ddfcb0655b2422df43d7c1ff46a3ce08e91b4e4df756a10f42f31d459?format=hex
    static ref deposit4_1_prev: Transaction = "0200000000010605902a1427b1922989fd7366ec8ed7c6de0d5b888ffe99b3b0509de94160b27a1300000000feffffff1a2e3c224ed75044ae136978cb2855418cb18b62f2331348e157bdedb5f83f530200000000feffffff47068de67bbf4c3ce23be9cceac8f453725e040b6006e4e79d84edccd1b9c9910d0000001716001426d5295bec5eb8aed12dc22540a14a2476342093feffffff534c50eb4c27c561271c6f87e3177e22ac831409b9bbb763624f7ef4ebe1f5ee000000006b483045022100f23f87858dc961011f70ee820ea775fa2792bf077504027508f0466af6c03a2202204947dcb50e97aedbaafe6cb9e490ffc7c03ba8caaea1056542e45d1d64806798012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff5d295ceaedad325d9ece875ae8bf0a711e62861edaba476acbc0d1597617d9ad2800000017160014feb3d71955579e074749d81078c4be222305be0dfeffffffa6bb491e4411987245dde52f02d289d82fe9ee2fdd99ee85123fb90475f87389010000006b483045022100cbb3ea7840cbbfc9b6b53798de7670f4f47c0ee51b979fe0bba942e7c5e6e90802201aa630d2492a23afbf9ef6160ed35166d7be1aabfd6b0bfeb12fb9ed1ae8a084012102679a681d9b5bf5c672e0413997762664a17009038674b806bf27dd6b368d9b67feffffff380e8e8f00000000001976a914852af22032c9ad32a62627a533f71255782eaf9188ace07072000000000017a9142a31551e56aac18e980848f0df59ae024353ca828730c11d00000000001976a9145bd47bbb245d5013f736818f4e7eb47e595726ba88ac87959400000000001976a91493f9354ad3c0454119ba546dcd7f6f15e1ee768c88aca21f03000000000017a91469f3764fe0754690eeb01495f5e2334a0f231c24876f026700000000001976a914fffcc492c21d6cd1faecebc38431ae1e1184cf8788acc1db3f00000000001976a9140f329efbb7a34f7deef6526f5692d8e1de3c934d88ac085d01030000000017a914c5d7e3fa811820b80c77631906fab769d390c46687b15798020000000017a9143b17eea03063871a835e3edb12d18ce0d14a6afd87f0fdc6040000000017a91428fb21f33818f1a22bb217dfb9ec84df1c5bfca98748405d1f0000000017a914a2c650766072b4edb9827dcec023ae370fca48cd87181681000000000017a91489d93daa9648db603beb08a568a77f22b27024db8790d00300000000001976a914ef193d99439319243d05f28dbe6c719e4cb0f29b88ac549c7a030000000017a91469f3754d4e8ce4fc60f63860ac565090ca15322d87d01213000000000017a9148b1ebd8786704a5d7e120dcdedbf9e18f5bc71998749434b000000000017a9146839f482da1f054f5b5edf8fc7dbca5a37da36d38732c32c010000000017a91422242ec77730029750718a3247fcb7f7dcee0a1c87aa7558000000000017a91470f910be383e5039453a4236e5202582d178f9cd87af080600000000001976a914480d71e0fe8924b38b5af9392086012baa2009ae88ac6cfc05000000000017a91469f375730ae7dc3322f90d9e64dd2829a54662878777db73000000000017a9146d050dafac4bebd8c1e145f8d16a112601c6ef8d877f9d30000000000017a9142b23de773d1a1dfee5dbb61efd4c42a65f51aafa870d5026000000000017a91469f3745d65c22567ad021af9ef639c746b4546c887a0db5b000000000017a9143aa15acdc5c3f336393b825f6b7bec8ed42276578740420f000000000017a91408550f1e561c4104c83aa6630512279484ba525087b0dfe011000000001976a914c83652834ee80cd62fb233b8abf4564cb8ae792a88ac3cc04702000000001976a9145ee3ae8021ef53d6782e894a50d4ec01bc5a485e88ace64a0a000000000017a9146f764926c3a4cfdf367ecc71b06b8add799ca87b877a1f3f00000000001976a914ce19be113d05cdba3e7d3f2130af7e38d36667f588ac5f670f00000000001976a9143bcea7339cdcddfe8d602486d371e12b04f3b21688ac332c17000000000017a91433fa1138c9a853a89a30edee8313f214abba8f1f87f00a47000000000017a91454ac49cf65daa2b80d8110c06ef3e88fb784786e872774f0000000000017a9142e2b94ef5fb667b126b6f87e8e6784c3b86b001f872b9d470a0000000017a9140cb056a962a35f81525fc8c400d59b6ee737f333874690d5000000000017a9147f8a86c1418dc9be4ea826e126c11a54143782e787a0252600000000001976a91416fcdfd56886f349d6c07f10411094a2583743f488acb4b89700000000001976a914f3ba40ed950ddb2bd961528ed0a51005aabc94a188acb0c1ce000000000017a9142cea9893daee62c4dd3c0d1079cc374e506dc0c88780841e000000000017a914b6b48721f27546d1bca0183c86328a33f2fe64e3872ce42f00000000001976a914fd0a487999d103ac7022487efd2d7e5fad5cdc0688ac61e01700000000001976a914e03cf1eaa1319456959a341179dfefb7eb48de7388ac00350c00000000001976a914e6e6a54b24c20b623ce82a1e25f2e21ba7817c9f88ac515702000000000017a9144e71b1c2cfba9952ad030edc84d1f81a4bb2d6318741533100000000001976a914a49029f17a5e9b00c791dbc356ecf4fe0f2b09a988ac82146700000000001976a9145f7a305ad546c9aa1ef3ac9fc2f0234571f3e4c788acf8f263000000000017a914fe6cdc08f94326010a9e47c57fb77bb5dcf49ab9873a9c9208000000001976a914dbda20636a4596c7b67e0803607f082f63ee913788acedb6d900000000001976a914985f919218a682f04c9f2ae001299797f4c4528888acf65121000000000017a914eb2c94ce02523397ec86fd1ad8bcea8397d9be0d8790d00300000000001976a914578bc19526421c4b0881c710ab462d7216be31c488ac99d4c000000000001976a9140300f22e36ab3529783dd0aaee73db88e8fbb91688ac9d9d4700000000001976a9149ad1b1b16afea2f01e079992167720328275a36b88acfc620c00000000001976a9147e4b6fc1da1004c4d52db33157c389c46d9b2b4088ac19941e000000000017a914ca3d638c6030eddca3fe6d5db68313de9703778387258488010000000017a914a1a5bfa969ddc8face5c161eabc631476805cd6087a88a45000000000017a914628ec99a8533f0e490f4b8dcca291b8cf1f45fd88702473044022063ca663c5612da9a7622cce8cc67ae5b1e4ae53b52e7ecb4ec9f4df939fadb11022050cdc5423123f2a74a5541a393f55abbb70db129767b55297bb8e34dc7cc8d47012103ec7b3b912749e551205aaaacc27baf89f1a64884af8d59636bee73cb8d4ee9f1024730440220353421959398ec54c40145da77ac5e879a835550e7531e735b16d1a22d32745102207f837a4bcaa4879e7509503a2867f0431ca368bd4abd294f8ff1d40e0df9c78201210202895b660b70e3c1d054075f7b5c630b53c8106c14d69d766ec95460bcb092bb024830450221009e99f216a38a45c7fcab96e878cc1f195e070c445dad66f801ae5fbdf86e1c35022036fb1569275ad114a1ecd3862fa69b9243c781fedbe387edb22db2275a8dc6a2012102c87a847935425aafdb43cadb9d8c5a189f64d21813ad47aa60202d65ca5769210002473044022048eac50a4cda883d7dde6e65e76dc2cdfc0c8a0954ef7a7793c00ce06b87cf2c02205b8b8e91e07ad43f2480a78626501cd986bfde4f42ff9d3eebef0b6ddfd71ed6012103b11a13c7158b6a7582eb328de4dd280e462acf7effbb506c9602ca585151b6210096d00800".parse().unwrap();
    static ref deposit4_addr: Vec<u8> = b"17ZykyawqVaoMdLd95WVqfMtyaMeKYNLUY".to_vec();
    static ref account4: AccountId = "0x9710ec40b7010e92b785778da44c1d87084ef2feb43f88710a0d0540e62480b6".parse().unwrap();

    // https://blockchain.info/rawtx/85927c4a4ca6e9665c9a8eae77dc3b5bc5b94da6dddf141f4ebcc93f0074a630?format=hex
    static ref hot_to_cold: Transaction = "0100000005671d9253e86b9a3a1d7194ba0cca7f91e10f3e987ab00c2e67e9228454b830ef00000000fc0047304402206a5856b2638a5c46209488d5a05ef49a8e8daf72e006fd70962d0dadf72fcfa902205a01eba3597d2f04c40c8f82e4e078a2e90a7bf69340b01923621e2b7a3307df0147304402207fec1df824c8e6877865b8a1e229106784cabd741fe305d9e7643a6fad10aa6402202c642e9bd8eb1c97e036243e95fbbeb41ae0926477892aef42ee6b35170b4a37014c69522102df92e88c4380778c9c48268460a124a8f4e7da883f80477deaa644ced486efc6210244d81efeb4171b1a8a433b87dd202117f94e44c909c49e42e77b69b5a6ce7d0d2103a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad10253aeffffffff1d99938500ea2152ea501691e60412ec84b168d7c9d145b83a18dc7fc4fb517200000000fc0047304402205a65710088b90c175dfbda220b1a390312e8edf0d9f937e4667532ad3c1c19bf022059ad3a7c121fae9f463200b46f56c68ae7c56d57442dcf2a69d35dfacbbf20e801473044022073a79c290f9933c220839d59fe5a32d22c0353fbe3a45e9ca4f5ac0f37b50480022068df068630f05aa0d2ec858c33f238e095d07feca1270d21b7abc93c5a1422f2014c69522102df92e88c4380778c9c48268460a124a8f4e7da883f80477deaa644ced486efc6210244d81efeb4171b1a8a433b87dd202117f94e44c909c49e42e77b69b5a6ce7d0d2103a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad10253aeffffffff897f6db5e855b301111b53a5c1f5e77b9cf2887c8167c8d93347501edf37627100000000fdfd0000483045022100db8e8c95538a95eeeb21c248a671caf65e1efabd88afa8f959a5ed716ec3137c02207b4ec6482e95421818875a855d0f1d4f455624d604c141f839efd37079e17225014730440220149adfd87a3e77405dbc9f7e396a77183010230d7faba0efa086ed9c7ba78e4602205e96b093882bc967bea130238779a714c5998fef785f2bfe834d7314b9fc559d014c69522102df92e88c4380778c9c48268460a124a8f4e7da883f80477deaa644ced486efc6210244d81efeb4171b1a8a433b87dd202117f94e44c909c49e42e77b69b5a6ce7d0d2103a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad10253aeffffffff98a3d907187d27d7aebb8ba9f29550d97f577a6e4ced57b7ca18f65f855d28de00000000fdfd0000483045022100bee5f7676558627491795f5c4b0fe7f653d4f7e8bc7b78890bed89104213949f02202661e66f6f0bc87298886bcde757598f89b49bb99de0e9338fc61baa1468dc74014730440220470d9faf21e5137cc1cf992e1f8c8c4f959c48f16652c6dca8bab551f327c203022027ee1ace4afc9a1d732b111c8cb7562f4cc019788ba7d16b2a4c19dd1bbe303c014c69522102df92e88c4380778c9c48268460a124a8f4e7da883f80477deaa644ced486efc6210244d81efeb4171b1a8a433b87dd202117f94e44c909c49e42e77b69b5a6ce7d0d2103a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad10253aeffffffff6937c6ea93db01dad6f1e1ec1486a81bb564404e8982d61bb06ccfae3c78b25b00000000fdfd000048304502210082bf0ce6fe9e01612bc2936a3fb8a2cfa945079883cbac373a4e0ff9768cb629022006c8438af0b1dad4cf7fdb82f419e7e872cbdf6bffaa32cbe47c43d7080e1deb014730440220383256e2036c98a71313f61b8d00396d085a17d4db721d913355816787f7264e02203d278910e39a915a4760f43889f01d63579523e698a17f58c2673077ac375b37014c69522102df92e88c4380778c9c48268460a124a8f4e7da883f80477deaa644ced486efc6210244d81efeb4171b1a8a433b87dd202117f94e44c909c49e42e77b69b5a6ce7d0d2103a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad10253aeffffffff0130a5397b0200000017a91495a12f1eba77d085711e9c837d04e4d8868a83438700000000".parse().unwrap();
    // https://blockchain.info/rawtx/ef30b8548422e9672e0cb07a983e0fe1917fca0cba94711d3a9a6be853921d67?format=hex
    static ref hot_to_cold_prev: Transaction = "0200000002de6ef0e10f3b2720656ee5ba5ace73b79591655919f430c1e25d7b02217488f7000000006a47304402206be4a8ce8351fcbc65c69aaf94d88627bdb95c6934d07d41e0fbb46c33dde78f02203e87caa040948753d31d041b3dcf2b9962026d2098880563c496543489ebf79f012103e5def80f7b9e69d38baf4abe0abebee2dca1695312b774a1eac689670842f74c00000000b07fa685eed8339bad0ed2445a262714db371d27e9e0f0cea6cb0951e00005ef010000006a47304402206e6b97e0750fa638a77065ca0f3084ce33ca66424d3a392c7b1b38c9d18cd3ec0220521b56830b5693f8858dc55c98592a5c35f72c343bbeb33f909294e9312b750b012103e5def80f7b9e69d38baf4abe0abebee2dca1695312b774a1eac689670842f74c00000000020001b2c40000000017a914cb94110435d0635223eebe25ed2aaabc03781c458764620000000000001976a914072b636ab218bbc498bafb92d9eff3f8ca4edbfc88ac00000000".parse().unwrap();

    // https://blockchain.info/rawtx/294e61b76f199ce44e74f2cbed6d8b9cd9627893e15a72492a0e004a012680f0?format=hex
    static ref cold_to_hot: Transaction = "0100000001b2c4ad4a3f1b19d5a64f1d45c92807fb6ad93b9fe1f51f4d72350e1581cea8b000000000fc004730440220043baf4a2ee4d5b0208e0fa3953688674e0d3014d716002854e6212102e598860220177fbefa231572e87a04cdb3c97a1d684ea32fac230f36af16a05cf343ac96d5014730440220664e10b79679ef7dfd2c2e73cb3b460dd845e0adf1f34fe6a773d13c1f706d4b022006da54f26b35388ad2273c350b5e88c6255c3322e28f1fd63b376d1f09edc5c9014c6952210386b58f51da9b37e59c40262153173bdb59d7e4e45b73994b99eec4d964ee7e882102e4631e46255571122d6e11cda75d5d601d5eb2585e65e4e87fe9f68c7838a278210263d46c760d3e04883d4b433c9ce2bc32130acd9faad0192a2b375dbba9f865c353aeffffffff01c0980b000000000017a914cb94110435d0635223eebe25ed2aaabc03781c458700000000".parse().unwrap();
    // https://blockchain.info/rawtx/b0a8ce81150e35724d1ff5e19f3bd96afb0728c9451d4fa6d5191b3f4aadc4b2?format=hex
    static ref cold_to_hot_prev: Transaction = "0100000001bf93892207f129af5ddc79baa9efb867c81397771089e4bc5086c7cce740eefd00000000fc00473044022037cdfc2df3c3a81848d8824c6ac28ab6f6c3570bd154c26817f6d29417db253e02207aaf4a6a0b9d277b2cffed46cce8183c7425617edc07d61e7363464fca8f53c3014730440220559f0d08838e1d9e0af6743ba57decab130f7f5327684ac4dedbcbc14982165302206542eb1ed21f894b36029ef8d02ee9d1af99e7203b709cb91b6261a73e5dcb47014c69522102df92e88c4380778c9c48268460a124a8f4e7da883f80477deaa644ced486efc6210244d81efeb4171b1a8a433b87dd202117f94e44c909c49e42e77b69b5a6ce7d0d2103a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad10253aeffffffff0120830c000000000017a91495a12f1eba77d085711e9c837d04e4d8868a83438700000000".parse().unwrap();

    // https://blockchain.info/rawtx/62c389f1974b8a44737d76f92da0f5cd7f6f48d065e7af6ba368298361141270?format=hex
    static ref withdraw: Transaction = "0100000001052ceda6cf9c93012a994f4ffa2a29c9e31ecf96f472b175eb8e602bfa2b2c5100000000fdfd000047304402200e4d732c456f4722d376252be16554edb27fc93c55db97859e16682bc62b014502202b9c4b01ad55daa1f76e6a564b7762cd0a81240c947806ab3f3b056f2e77c1da01483045022100c7cd680992de60da8c33fc3ef7f5ead85b204660822d9fbda2d85f9fadba732a022021fdc49b20a6007ea971a385732a4065d1d7c792ac9dc391034fb78aa9f5034b014c69522102df92e88c4380778c9c48268460a124a8f4e7da883f80477deaa644ced486efc6210244d81efeb4171b1a8a433b87dd202117f94e44c909c49e42e77b69b5a6ce7d0d2103a36339f413da869df12b1ab0def91749413a0dee87f0bfa85ba7196e6cdad10253aeffffffff03e0349500000000001976a91413256ff2dee6e80c275ddb877abc1ffe453a731488ace00f9700000000001976a914ea6e8dd56703ace584eb9dff0224629f8486672988acc88a02000000000017a914cb94110435d0635223eebe25ed2aaabc03781c458700000000".parse().unwrap();
    // https://blockchain.info/rawtx/512c2bfa2b608eeb75b172f496cf1ee3c9292afa4f4f992a01939ccfa6ed2c05?format=hex
    static ref withdraw_prev: Transaction = "02000000018554af3a19f2475bb293e81fe123b588a50d7c86ce97ed4f015853b427e45f12040000006a473044022037957f493964792e6bedd37aa5193892bd9fdb5d974d87f5334f36b0d544c7f202203d7bb2ac644204437b77e9c34ea5bf875da41d728ef7352c9d74ff507da64502012102bd47917d4cf403ca8e9cb71c84a127e0451686877fe186614385025ccd1ed9cc000000000260a62f010000000017a914cb94110435d0635223eebe25ed2aaabc03781c45870000000000000000366a343552547a425a4d3274346537414d547442534e3853424c3878316b716e39713769355a75566e3569537876526341326b40484c5400000000".parse().unwrap();
}

fn mock_detect_transaction_type<T: Trait>(
    tx: &Transaction,
    prev_tx: Option<&Transaction>,
) -> BtcTxMetaType<T::AccountId> {
    let btc_tx_detector = BtcTxTypeDetector::new(
        Network::Mainnet,
        0,
        (
            DEPOSIT_HOT_ADDR.parse::<Address>().unwrap(),
            DEPOSIT_COLD_ADDR.parse::<Address>().unwrap(),
        ),
        None,
    );
    btc_tx_detector.detect_transaction_type::<T::AccountId, _>(tx, prev_tx, |script| {
        T::AccountExtractor::extract_account(script)
    })
}

#[test]
fn test_detect_tx_type() {
    set_default_ss58_version(Ss58AddressFormat::ChainXAccount);

    match mock_detect_transaction_type::<Test>(&deposit1, None) {
        BtcTxMetaType::Deposit(_) => {}
        _ => unreachable!("wrong type"),
    }
    match mock_detect_transaction_type::<Test>(&deposit2, None) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_none() && info.op_return.is_some())
        }
        _ => unreachable!("wrong type"),
    }

    match mock_detect_transaction_type::<Test>(&deposit3_0, None) {
        BtcTxMetaType::Deposit(_) => {}
        _ => unreachable!("wrong type"),
    }
    // tx without opreturn, no input addr would parse nothing
    match mock_detect_transaction_type::<Test>(&deposit3_1, None) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_none() && info.op_return.is_none())
        }
        _ => unreachable!("wrong type"),
    }
    // then provide prev tx
    match mock_detect_transaction_type::<Test>(&deposit3_1, Some(&deposit3_1_prev)) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_some() && info.op_return.is_none())
        }
        _ => unreachable!("wrong type"),
    }

    // tx without opreturn, no input addr would parse nothing
    match mock_detect_transaction_type::<Test>(&deposit4_0, None) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_none() && info.op_return.is_none())
        }
        _ => unreachable!("wrong type"),
    }
    // then provide prev tx
    match mock_detect_transaction_type::<Test>(&deposit4_0, Some(&deposit4_0_prev)) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_some() && info.op_return.is_none())
        }
        _ => unreachable!("wrong type"),
    }
    match mock_detect_transaction_type::<Test>(&deposit4_1, None) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_none() && info.op_return.is_some())
        }
        _ => unreachable!("wrong type"),
    }

    // hot_to_cold
    // if not pass a prev, would judge to a deposit, but this deposit could not be handled due to
    // opreturn and input_addr are all none, or if all send to cold, it would be Irrelevance
    match mock_detect_transaction_type::<Test>(&hot_to_cold, None) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_none() && info.op_return.is_none())
        }
        _ => unreachable!("wrong type"),
    }
    // then if provide prev, it would be judge to a HotAndCold
    match mock_detect_transaction_type::<Test>(&hot_to_cold, Some(&hot_to_cold_prev)) {
        BtcTxMetaType::HotAndCold => {}
        _ => unreachable!("wrong type"),
    }

    // cold_to_hot
    // if not pass a prev, would judge to a deposit, but this deposit could not be handled due to
    // opreturn and input_addr are all none
    match mock_detect_transaction_type::<Test>(&cold_to_hot, None) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_none() && info.op_return.is_none())
        }
        _ => unreachable!("wrong type"),
    }
    // then if provide prev, it would be judge to a HotAndCold
    match mock_detect_transaction_type::<Test>(&cold_to_hot, Some(&cold_to_hot_prev)) {
        BtcTxMetaType::HotAndCold => {}
        _ => unreachable!("wrong type"),
    }

    // withdraw
    // if not pass a prev, would judge to a deposit due to withdraw change.
    // if no change, would be Irrelevance
    // but this deposit could not be handled due to opreturn and input_addr are all none
    match mock_detect_transaction_type::<Test>(&withdraw, None) {
        BtcTxMetaType::Deposit(info) => {
            assert!(info.input_addr.is_none() && info.op_return.is_none())
        }
        _ => unreachable!("wrong type"),
    }
    // then if provide prev, it would be judge to a HotAndCold
    match mock_detect_transaction_type::<Test>(&withdraw, Some(&withdraw_prev)) {
        BtcTxMetaType::Withdrawal => {}
        _ => unreachable!("wrong type"),
    }
}

fn mock_process_tx<T: Trait>(tx: Transaction, prev_tx: Option<Transaction>) -> BtcTxState {
    let network = Network::Mainnet;
    let min_deposit = 0;
    let current_trustee_pair = (
        DEPOSIT_HOT_ADDR.parse::<Address>().unwrap(),
        DEPOSIT_COLD_ADDR.parse::<Address>().unwrap(),
    );
    let previous_trustee_pair = None;
    process_tx::<T>(
        tx,
        prev_tx,
        network,
        min_deposit,
        current_trustee_pair,
        previous_trustee_pair,
    )
}

#[test]
fn test_process_tx() {
    set_default_ss58_version(Ss58AddressFormat::ChainXAccount);
    ExtBuilder::default().build_and_execute(|| {
        let r = mock_process_tx::<Test>(deposit1.clone(), None);
        assert_eq!(r.result, BtcTxResult::Success);
        let r = mock_process_tx::<Test>(deposit2.clone(), None);
        assert_eq!(r.result, BtcTxResult::Success);

        // 3
        // with opreturn, and log input_addr => accountid map
        let r = mock_process_tx::<Test>(deposit3_0.clone(), None);
        assert_eq!(r.result, BtcTxResult::Success);
        assert_eq!(XAssets::usable_balance(&account3, &X_BTC), 100000000);
        // due to no deposit, would not record input_addr
        assert_eq!(XGatewayCommon::bound_addrs(&account3), Default::default());

        // no prev, would judge a failed deposit
        let r = mock_process_tx::<Test>(deposit3_1.clone(), None);
        assert_eq!(r.result, BtcTxResult::Failure);
        // with prev, would deposit use the input_addr, but due to no relationship of addr
        // and accountid before, thus this become a cache deposit
        let r = mock_process_tx::<Test>(deposit3_1.clone(), Some(deposit3_1_prev.clone()));
        assert_eq!(r.result, BtcTxResult::Success);
        assert_eq!(
            XGatewayBitcoin::pending_deposits(&deposit3_addr.to_vec()),
            vec![BtcDepositCache {
                txid: deposit3_1.hash(),
                balance: 190850000
            }]
        );

        // 4
        let r = mock_process_tx::<Test>(deposit4_0.clone(), None);
        assert_eq!(r.result, BtcTxResult::Failure);
        let r = mock_process_tx::<Test>(deposit4_0.clone(), Some(deposit4_0_prev.clone()));
        assert_eq!(r.result, BtcTxResult::Success);
        assert_eq!(
            XGatewayBitcoin::pending_deposits(&deposit4_addr.to_vec()),
            vec![BtcDepositCache {
                txid: deposit4_0.hash(),
                balance: 100000000
            }]
        );
        // use a tx with opreturn to release deposit cache, must have prev
        // (if not have prev, just deposit this tx success, but not release deposit cache. Deposit
        // cache need a more opreturn tx with prev to release)
        let r = mock_process_tx::<Test>(deposit4_1.clone(), Some(deposit4_1_prev.clone()));
        assert_eq!(r.result, BtcTxResult::Success);
        // release the cache
        assert_eq!(
            XGatewayBitcoin::pending_deposits(&deposit4_addr.to_vec()),
            vec![]
        );
        // deposit cache and current deposit
        assert_eq!(
            XAssets::usable_balance(&account4, &X_BTC),
            100000000 + 387439
        );

        // hot and cold
        let r = mock_process_tx::<Test>(hot_to_cold.clone(), None);
        assert_eq!(r.result, BtcTxResult::Failure);
        let r = mock_process_tx::<Test>(hot_to_cold.clone(), Some(hot_to_cold_prev.clone()));
        assert_eq!(r.result, BtcTxResult::Success);

        let r = mock_process_tx::<Test>(cold_to_hot.clone(), None);
        assert_eq!(r.result, BtcTxResult::Failure);
        let r = mock_process_tx::<Test>(cold_to_hot.clone(), Some(cold_to_hot_prev.clone()));
        assert_eq!(r.result, BtcTxResult::Success);

        // withdraw
        WithdrawalProposal::<Test>::put(BtcWithdrawalProposal {
            sig_state: VoteResult::Unfinish,
            withdrawal_id_list: vec![],
            tx: withdraw.clone(),
            trustee_list: vec![],
        });

        let r = mock_process_tx::<Test>(withdraw.clone(), None);
        assert_eq!(r.result, BtcTxResult::Failure);
        let r = mock_process_tx::<Test>(withdraw.clone(), Some(withdraw_prev.clone()));
        assert_eq!(r.result, BtcTxResult::Success);
    })
}

#[test]
fn test_push_tx_call() {
    set_default_ss58_version(Ss58AddressFormat::ChainXAccount);
    // https://blockchain.info/rawtx/f1a9161a045a01db7ae02b8c0531e2fe2e9740efe30afe6d84a12e3cac251344?format=hex
    let normal_deposit: Transaction = "0200000003a50c032806a643a0ad85803ff77e0ecb58baf327bcc91e269945402c551fada5000000006a473044022031d06016a6e996a07ca1881c70fc328b4ca075d80f5284378c11c9fc018112c00220480b8371bf9967da2af205dacc7ee4ff880b1bebd6c8a77f3cd24bae425c672f01210223222d4d30dce7a7842b4d38e467eb93680f610a5156d8ef18918682a1010396000000003fd0c0f65304982c8ff0ce9a38bcdffc8afdf8e76f1ff518a0db3fa943992f94590000006a473044022012e3920b2e2a45f6c28667f5854f894077b140a8267c6da0069fcf9c541e4db60220382e1f09267ba2f3d2d2a7bf77daf8b9bdacc6693b760d477657cd0b64bdf7c801210223222d4d30dce7a7842b4d38e467eb93680f610a5156d8ef18918682a1010396000000009d61e22d5434504c247ffb5be5a744a513b1cf274da8be492e401495b2aaafd0180000006b48304502210097491bd7c5aad0fca30b022b3d7bbae50dcd3658dddd4dd9ab6da6217863c7f902205e8ef79cf2f8620398de9812f5d5a5cb04e96f674a9f1af9e872b82623de802d01210223222d4d30dce7a7842b4d38e467eb93680f610a5156d8ef18918682a101039600000000032077fc020000000017a914cb94110435d0635223eebe25ed2aaabc03781c45871a7c0000000000001976a91427f82ed8de307712c1f5fbbb3a52a96163449c3d88ac00000000000000003d6a3b355555716e46544e52596d656b6d5a4e5375335041695050476b737635746169373752625a366173365468773837704a40436861696e5846616e7300000000".parse().unwrap();
    let tx = serialization::serialize(&normal_deposit);
    let headers = generate_blocks_576576_578692();
    let block_hash = headers[&577667].hash();

    let raw_proof= hex::decode("7a0a00000df93909095e26bc2226c7a308a197623e1338d97205dab31e8bb1938fdd1ffb750120040316fc943d5a2d2a2034a0fe563e0e32298a13a826bfdf9c70779586dba5271dce89f50cee96759a25b44b975c073f3ba6a12a92209494709907cb15922eac15e16ae180f9e63d96e25e1c8056b34f194a8a0d2f14bd935e9c2abc79dd8d0c425975eac4696b4d5bca42d09ecb27b7397e1061d138b69c9283fb47337aa61179b15b17ee942e635d5c9479b337ba1877054708336fca85d3e64fb4519ce5319ea3940b45a0a2be630ffc8091c23199e3468ec08e6e49aa7d2097614c22441325ac3c2ea1846dfe0ae3ef40972efee231058c2be07adb015a041a16a9f1dc9e699c56bbfb3e7dc751ea295188f5af86348789547c58981341ddb1eae528a1566ea4b17b099bb29d27728ccf398669eabd82ee4910eaccba7e5e40be6351d734b422020e5c57910de3a94f1eced6b1151333c425048a93f49c9e7110a77201b34ad3a09a12f3bdb8f1fce78c21ec868a32e36eef263077f047eaaa7c5842feee2b12a1651f1deaf50afcddbca8e2bfb36d707133dfa27235e72cc169fc0704d7ad0a00").unwrap();
    let proof: PartialMerkleTree = serialization::deserialize(Reader::new(&raw_proof)).unwrap();

    ExtBuilder::default().build_and_execute(|| {
        let confirmed = XGatewayBitcoin::confirmation_number();
        // insert headers
        for i in 576577..=577667 + confirmed {
            assert_ok!(XGatewayBitcoin::apply_push_header(headers[&i].clone()));
        }
        let info = BtcRelayedTxInfo {
            block_hash,
            merkle_proof: proof,
        };

        assert_ok!(XGatewayBitcoin::push_transaction(
            frame_system::RawOrigin::Signed(Default::default()).into(),
            tx.clone().into(),
            info.clone(),
            None,
        ));

        // reject replay
        assert_noop!(
            XGatewayBitcoin::push_transaction(
                frame_system::RawOrigin::Signed(Default::default()).into(),
                tx.clone().into(),
                info,
                None,
            ),
            XGatewayBitcoinErr::ReplayedTx,
        );
    });
}
